package io;

import io.IIO;
import io.command.*;
import io.command.result.*;

import card.Cardset;

/**
 * Top level of IO, control how the IO-related class process
 * 
 * 
 * @version 1.2.0
 */
public class IOManager {

	private IIO io;
	private IOCommandFactory commandFactory;

	public IOManager() {
		this.io = new ConsoleIO();
		this.commandFactory = new IOCommandFactory(io);
	}

	public IOManager(IIO io) {
		this(io, new IOCommandFactory(io));
	}

	public IOManager(IIO io, IOCommandFactory commandFactory) {
		this.io = io;
		this.commandFactory = commandFactory;
	}

	/**
	 * Player select cards
	 * 
	 * @param hand
	 * @param playerName
	 * @return play
	 */
	public Cardset ioPlayerSelectCards(Cardset hand, String playerName) {
		IOCommand displayCard = commandFactory.createHandDisplayCommand(hand,
				playerName);
		displayCard.execute();

		io.println("input>>: ");
		Cardset play = new Cardset(20);

		int result;
		do {
			IOCommand chooseCard = commandFactory.createCardInputCommand(hand);
			IOIntResult ioresult = (IOIntResult) chooseCard.execute();
			result = ioresult.getResult();

			if (result != -1)
				play.add(hand.getCard(result));
		} while (result != -1);
		return play;
	}

	/**
	 * Message of end game
	 */
	public void ioEndGameMessage() {
		IOCommand displayEndGameMessage = commandFactory
				.createEndGameMessageCommand();
		displayEndGameMessage.execute();
	}

	/**
	 * new player to start in new round
	 * 
	 * @param newRoundStarterName
	 */
	public void ioNewRoundMessage(String newRoundStarterName) {
		IOCommand diplayNewRoundMessage = commandFactory
				.createNewRoundMessageCommand(newRoundStarterName);
		diplayNewRoundMessage.execute();
	}

	/**
	 * show the play is not bigger than previous one
	 */
	public void ioNotBiggerPlayMessage() {
		IOCommand displayNotBiggerPlayMessage = commandFactory
				.createNotBiggerPlayMessageCommand();
		displayNotBiggerPlayMessage.execute();
	}

	/**
	 * show message of confirming play
	 * 
	 * @param play
	 * @return ioresult.getResult
	 */
	public char ioConfirmPlay(Cardset play) {
		IOCommand confirmPlayCommand = commandFactory
				.createConfirmPlayCommand(play);
		IOCharResult ioresult = (IOCharResult) confirmPlayCommand.execute();

		return ioresult.getResult();
	}

	/**
	 * show message on start the game again
	 * 
	 * @param winner
	 * @return ioresult.getResult
	 */
	public char ioContinueGame(String winner) {
		IOCommand continueGameCommand = commandFactory
				.createContinueGameCommand(winner);
		IOCharResult ioresult = (IOCharResult) continueGameCommand.execute();

		return ioresult.getResult();
	}

	/**
	 * Show message of the end of application
	 */
	public void ioEndApplicationMessage() {
		IOCommand endApplicationMessage = commandFactory
				.createEndApplicationMessageCommand();
		endApplicationMessage.execute();
	}

	/**
	 * Show message of elect a landlord
	 * 
	 * @param playerName
	 * @param hand
	 * @return ioresult.getResult
	 */
	public int ioPlayerLandlordRating(String playerName, Cardset hand) {
		IOCommand playerLandlordRating = commandFactory
				.createPlayerLandlordRatingCommand(playerName, hand);
		IOIntResult ioresult = (IOIntResult) playerLandlordRating.execute();

		return ioresult.getResult();
	}

}
